namespace C1.Win.C1FlexGrid
{
    using C1.Win.C1FlexGrid.Util.Styles;
    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;

    [StructLayout(LayoutKind.Sequential)]
    public struct CellRange
    {
        internal GridModel _grid;
        public int r1;
        public int c1;
        public int r2;
        public int c2;
        internal CellRange(GridModel grid, int row, int col)
        {
            this._grid = grid;
            this.r1 = this.r2 = row;
            this.c1 = this.c2 = col;
        }

        internal CellRange(GridModel grid, int row1, int col1, int row2, int col2)
        {
            this._grid = grid;
            this.r1 = row1;
            this.c1 = col1;
            this.r2 = (row2 >= 0) ? row2 : row1;
            this.c2 = (col2 >= 0) ? col2 : col1;
        }

        public bool IsSingleCell
        {
            get
            {
                return ((this.r1 == this.r2) && (this.c1 == this.c2));
            }
        }
        public bool IsValid
        {
            get
            {
                if (((this.r1 < 0) || (this.r2 < 0)) || (((this.c1 < 0) || (this.c2 < 0)) || (this._grid == null)))
                {
                    return false;
                }
                return ((!this._grid.IsBadCol(this.c1) && !this._grid.IsBadCol(this.c2)) && (!this._grid.IsBadRow(this.r1) && !this._grid.IsBadRow(this.r2)));
            }
        }
        public bool ContainsRow(int row)
        {
            if ((this.r1 < 0) || (this.r2 < 0))
            {
                return false;
            }
            return (((row >= this.r1) && (row <= this.r2)) || ((row >= this.r2) && (row <= this.r1)));
        }

        public bool ContainsCol(int col)
        {
            if ((this.c1 < 0) || (this.c2 < 0))
            {
                return false;
            }
            return (((col >= this.c1) && (col <= this.c2)) || ((col >= this.c2) && (col <= this.c1)));
        }

        public bool Contains(int row, int col)
        {
            return (this.ContainsRow(row) && this.ContainsCol(col));
        }

        public int TopRow
        {
            get
            {
                if (this.r1 > this.r2)
                {
                    return this.r2;
                }
                return this.r1;
            }
        }
        public int BottomRow
        {
            get
            {
                if (this.r2 < this.r1)
                {
                    return this.r1;
                }
                return this.r2;
            }
        }
        public int LeftCol
        {
            get
            {
                if (this.c1 > this.c2)
                {
                    return this.c2;
                }
                return this.c1;
            }
        }
        public int RightCol
        {
            get
            {
                if (this.c2 < this.c1)
                {
                    return this.c1;
                }
                return this.c2;
            }
        }
        public void Normalize()
        {
            if (this.r1 > this.r2)
            {
                int num = this.r1;
                this.r1 = this.r2;
                this.r2 = num;
            }
            if (this.c1 > this.c2)
            {
                int num2 = this.c1;
                this.c1 = this.c2;
                this.c2 = num2;
            }
        }

        internal void AssertValid()
        {
            if (!this.IsValid)
            {
                throw new Exception("Invalid CellRange for this operation");
            }
        }

        internal CellRange Delta(CellRange rg)
        {
            rg.Normalize();
            if ((rg.c1 == this.LeftCol) && (rg.c2 == this.RightCol))
            {
                if (rg.r1 == this.TopRow)
                {
                    rg.r1 = Math.Min(rg.r2, this.BottomRow);
                    rg.r2 = Math.Max(rg.r2, this.BottomRow);
                    return rg;
                }
                if (rg.r2 == this.BottomRow)
                {
                    rg.r2 = Math.Max(rg.r1, this.TopRow);
                    rg.r1 = Math.Min(rg.r1, this.TopRow);
                    return rg;
                }
            }
            if ((rg.r1 == this.TopRow) && (rg.r2 == this.BottomRow))
            {
                if (rg.c1 == this.LeftCol)
                {
                    rg.c1 = Math.Min(rg.c2, this.RightCol);
                    rg.c2 = Math.Max(rg.c2, this.RightCol);
                    return rg;
                }
                if (rg.c2 == this.RightCol)
                {
                    rg.c2 = Math.Max(rg.c1, this.LeftCol);
                    rg.c1 = Math.Min(rg.c1, this.LeftCol);
                    return rg;
                }
            }
            rg.r1 = rg.r2 = rg.c1 = rg.c2 = -1;
            return rg;
        }

        public object Data
        {
            get
            {
                this.AssertValid();
                return this._grid.GetData(this.r1, this.c1);
            }
            set
            {
                this.AssertValid();
                for (int i = this.TopRow; i <= this.BottomRow; i++)
                {
                    for (int j = this.LeftCol; j <= this.RightCol; j++)
                    {
                        this._grid.SetData(i, j, value);
                    }
                }
            }
        }
        public string DataDisplay
        {
            get
            {
                this.AssertValid();
                return this._grid.GetDataDisplay(this.r1, this.c1);
            }
        }
        public CellStyle StyleNew
        {
            get
            {
                this.AssertValid();
                C1.Win.C1FlexGrid.Util.Styles.Style cellStyle = this._grid.GetCellStyle(this.r1, this.c1);
                if (cellStyle == null)
                {
                    cellStyle = this._grid._styles.AddInternal();
                    for (int i = this.TopRow; i <= this.BottomRow; i++)
                    {
                        for (int j = this.LeftCol; j <= this.RightCol; j++)
                        {
                            this._grid.SetCellStyle(i, j, cellStyle);
                        }
                    }
                }
                return new CellStyle(cellStyle);
            }
        }
        public CellStyle Style
        {
            get
            {
                this.AssertValid();
                C1.Win.C1FlexGrid.Util.Styles.Style cellStyle = this._grid.GetCellStyle(this.r1, this.c1);
                if (cellStyle == null)
                {
                    return null;
                }
                return new CellStyle(cellStyle);
            }
            set
            {
                C1.Win.C1FlexGrid.Util.Styles.Style style = (value != null) ? value._style : null;
                for (int i = this.TopRow; i <= this.BottomRow; i++)
                {
                    for (int j = this.LeftCol; j <= this.RightCol; j++)
                    {
                        this._grid.SetCellStyle(i, j, style);
                    }
                }
            }
        }
        public CellStyle StyleDisplay
        {
            get
            {
                this.AssertValid();
                return new CellStyle(this._grid.GetStyleDisplay(this.r1, this.c1));
            }
        }
        public CheckEnum Checkbox
        {
            get
            {
                this.AssertValid();
                return this._grid.GetCellCheck(this.r1, this.c1);
            }
            set
            {
                this.AssertValid();
                for (int i = this.TopRow; i <= this.BottomRow; i++)
                {
                    for (int j = this.LeftCol; j <= this.RightCol; j++)
                    {
                        this._grid.SetCellCheck(i, j, value);
                    }
                }
            }
        }
        public System.Drawing.Image Image
        {
            get
            {
                this.AssertValid();
                return this._grid.GetCellImage(this.r1, this.c1);
            }
            set
            {
                this.AssertValid();
                for (int i = this.TopRow; i <= this.BottomRow; i++)
                {
                    for (int j = this.LeftCol; j <= this.RightCol; j++)
                    {
                        this._grid.SetCellImage(i, j, value);
                    }
                }
            }
        }
        public object UserData
        {
            get
            {
                this.AssertValid();
                return this._grid.GetCellUserData(this.r1, this.c1);
            }
            set
            {
                this.AssertValid();
                for (int i = this.TopRow; i <= this.BottomRow; i++)
                {
                    for (int j = this.LeftCol; j <= this.RightCol; j++)
                    {
                        this._grid.SetCellUserData(i, j, value);
                    }
                }
            }
        }
        public string Clip
        {
            get
            {
                this.AssertValid();
                return this._grid.GetClipRange(this, false);
            }
            set
            {
                this.AssertValid();
                this._grid.SetClipRange(this, value, false);
            }
        }
        public void Clear(ClearFlags clear)
        {
            this.AssertValid();
            for (int i = this.TopRow; i <= this.BottomRow; i++)
            {
                for (int j = this.LeftCol; j <= this.RightCol; j++)
                {
                    this._grid.ClearCell(i, j, clear);
                }
            }
        }

        public override string ToString()
        {
            return string.Format("CellRange: ({0},{1})-({2},{3})", new object[] { this.r1, this.c1, this.r2, this.c2 });
        }
    }
}

